package com.shuzhi.stationarysource.common.jpa.model;


import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.domain.Auditable;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Optional;

/**
 * @version v1.0
 * @ProjectName: spring-demo
 * @ClassName: AbstractAuditModel
 * @Description: TODO(一句话描述该类的功能)
 * @Author: SunFeng
 * @Date: 2019/11/22 10:50
 */
@MappedSuperclass
@EntityListeners({AuditingEntityListener.class})
public abstract class AbstractAuditModel implements Auditable {
    private static final long serialVersionUID = -8388269103763562978L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @CreatedBy
    private String createdBy;

    @CreatedDate
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "createdDate")
    private LocalDateTime createdDate;

    @LastModifiedBy
    private String lastModifiedBy;

    @Column(name = "lastModifiedDate")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    @Version
    private long version;


    public AbstractAuditModel() {
    }

    @Override
    public Long getId() {
        return this.id;
    }

    protected void setId(Long id) {
        this.id = id;
    }

    @Override
    @Transient
    public boolean isNew() {
        return null == this.getId();
    }

    @Override
    public Optional<String> getCreatedBy() {
        return Optional.of(this.createdBy);
    }

    @Override
    public void setCreatedBy(Object createdBy) {
        this.createdBy = createdBy.toString();
    }

    @Override
    public Optional<LocalDateTime> getCreatedDate() {
        return Optional.of(this.createdDate);
    }

    @Override
    public void setCreatedDate(TemporalAccessor createdDate) {
        this.createdDate = LocalDateTime.from(createdDate);
    }

    @Override
    public Optional<String> getLastModifiedBy() {
        return Optional.of(this.lastModifiedBy);
    }

    @Override
    public void setLastModifiedBy(Object lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy.toString();
    }

    @Override
    public Optional<LocalDateTime> getLastModifiedDate() {
        return Optional.of(this.lastModifiedDate);
    }

    @Override
    public void setLastModifiedDate(TemporalAccessor lastModifiedDate) {
        this.lastModifiedDate = LocalDateTime.from(lastModifiedDate);
    }

    public long getVersion() {
        return this.version;
    }

    public void setVersion(long version) {
        this.version = version;
    }


    @Override
    public String toString() {
        return String.format("Entity of type %s with id: %s", this.getClass().getName(), this.getId());
    }

    @Override
    public boolean equals(Object obj) {
        if (null == obj) {
            return false;
        } else if (this == obj) {
            return true;
        } else if (!this.getClass().equals(obj.getClass())) {
            return false;
        } else {
            Persistable<?> that = (Persistable) obj;
            return null == this.getId() ? false : this.getId().equals(that.getId());
        }
    }

    @Override
    public int hashCode() {
        int hashCode = 17;
        hashCode = hashCode + (null == this.getId() ? 0 : this.getId().hashCode() * 31);
        return hashCode;
    }

}
